
#include "etl_list.h"
#include "etl_string.h"
#include "etl_xml.h"
#include "etl_dir.h"

#include <assert.h>

using namespace etl;
using namespace std;

int main( int argc, char* argv[] )
{
  
  {
    etl_string a;
    assert( a.length() == 0 );
  }

  {
    etl_string a = "foo";
    etl_string b = a;
    assert( a.length() == 3 );
    assert( b.length() == 3 );
    assert( a == b );
  }

  {
    etl_string a = (long)10;
    assert( a.length() == 2 );
  }

  {
    etl_string a = (unsigned long)10;
    assert( a.length() == 2 );
  }

  {
    etl_string a = (double)10;
    assert( a.length() == 9 ); // "10.000000
  }

  {
    etl_string a = "I swear, by my life and my love of it...";
    assert( strlen(a.c_str()) == 40 );
  }

  {
    etl_string a = "I swear, by my life and my love of it...";
    assert( strlen(a.c_str()) == 40 );
  }

  {
    etl_string a = "I swear, by my life and my love of it...";
    etl_string b = "foo";

    b = a;
    assert( a == b );
  }

  {
    etl_string a = "I swear, by my life and my love of it...";
    etl_string b = "foo";

    assert( a != b );
  }

  {
    etl_string a = "I swear, by my life and my love of it...";

    assert( a.ends_with( "love of it..." ) );
  }

  {
    etl_string a = "I swear, by my life and my love of it...";

    assert( a.begins_with( "I swear, by" ) );
  }

  {
    etl_string a = "I swear, by my life and my love of it...";

    assert( a.contains( " my life and my " ) );
  }

  {
    etl_string a;
    a.format( (char*)"I have %d friends, %d faithful friends, more faithful could not be; and every night, by the dim firelight, they come to sit with me.", 2, 2 );
    assert( a == "I have 2 friends, 2 faithful friends, more faithful could not be; and every night, by the dim firelight, they come to sit with me." );    
  }

  {
    etl_string a = "the first half ";
    etl_string b = "of the sentence.";
    etl_string c = a + b;
    assert( c == "the first half of the sentence." );
  }

  {
    etl_string a = "the first half ";
    etl_string b = "of the sentence.";
    etl_string c = a + b;
    assert( c == "the first half of the sentence." );
  }

  {
    etl_string a = "the first half ";
    a += "of the sentence.";
    assert( a == "the first half of the sentence." );
  }

  {
    etl_string a = "Find the weasel.";
    etl_string sub = a.sub_string( 5, 3 );
    assert( sub == "the" );
  }

  {
    etl_string a = "Find the weasel.";
    etl_list<etl_string> parts;
    a.split( " ", parts );

    parts.iter_begin();

    etl_string first;
    first = *parts.iter_data();
    parts.iter_next();

    etl_string second;
    second = *parts.iter_data();
    parts.iter_next();

    etl_string third;
    third = *parts.iter_data();
    parts.iter_next();

    assert( first == "Find" );
    assert( second == "the" );
    assert( third == "weasel." );
  }

  {
    etl_string a = "I swear, by my life and my love of it..";
    a.remove( 'e' );
    assert( a == "I swar, by my lif and my lov of it.." );
  }

  {
    etl_string a = "I swear, by my life and my love of it..";
    a.from_long( (long)10 );
    assert( a == "10" );
  }

  {
    etl_string a = "I swear, by my life and my love of it..";
    a.from_ulong( (unsigned long)10 );
    assert( a == "10" );
  }

  {
    etl_string a = "I swear, by my life and my love of it..";
    a.from_double( (double)10 );
    assert( a == "10.000000" );
  }

  {
    etl_string a = "10";
    assert( (a.to_long() * 10) == 100 );
  }

  {
    etl_string a = "10";
    assert( (a.to_ulong() * 10) == 100 );
  }

  {
    etl_string a = "10";
    assert( (a.to_double() * 10) == 100 );
  }


  {
    etl_string a = "I swear, by my life and my love of it..";
    a.to_lower();
    assert( a == "i swear, by my life and my love of it.." );
  }

  {
    etl_string a = "I swear, by my life and my love of it..";
    a.to_upper();
    assert( a == "I SWEAR, BY MY LIFE AND MY LOVE OF IT.." );
  }

  {
    unsigned char buf[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    etl_string encodedData = etl_string::to_base64( buf, 10 );

    assert( encodedData == "AQIDBAUGBwgJCg==" );

    unsigned char* buf2 = NULL;

    encodedData.from_base64( &buf2 );

    assert( memcmp( buf, buf2, 10 ) == 0 );
  }

  // regexp tests

  {
    etl_string src = "This is an end match.";

    int ret = src.match( (char*)"end match.$" );

    assert( ret == 1 );
  }

  {
    etl_string src = "This is a begin match.";

    int ret = src.match( (char*)"^This is a begin " );

    assert( ret == 1 );
  }

  {
    etl_string src = "This is a single char match.";

    int ret = src.match( (char*)".his is a single char match." );

    assert( ret == 1 );
  }

  {
    etl_string src = "TTTTTThis is a star match.";

    int ret = src.match( (char*)"T*his is a star match." );

    assert( ret == 1 );
  }

  {
      etl_string src = "I swear, by my life and my love of it...";
      int forwardPos = src.find( "swear" );
      assert( forwardPos == 2 );
  }

  {
      etl_string src = "I swear, by my life and my love of it...";
      int backwardPos = src.rfind( "my" );
      assert( backwardPos == 24 );
  }

  {
    etl_xml xml;
    assert( xml.set_document("<?xml  version=\"1.0\"?><user_db num_users=\"3\"><user name=\"tony\" age=\"27\">TONY</user><user name=\"brad\" age=\"27\">BRAD</user>    <user name=\"brent\" age=\"27\">BRENT</user>  </user_db>  <foo><bar><foobar></foobar><goobar></goobar><hoobar></hoobar></bar><hi><dude></dude></hi></foo>") == 0 );

    etl_xml_node* root = xml.parse();
    assert( root != NULL );

    etl_list<etl_xml_node*> parts;
    parts = xml.search_for_all( "user", root );
    assert( parts.count_elements() == 3 );
  }

  {
    etl_xml xml;
    assert( xml.set_document("<?xml  version=\"1.0\"?><user_db num_users=\"3\"><user name=\"tony\" age=\"27\">TONY</user><user name=\"brad\" age=\"27\">BRAD</user>    <user name=\"brent\" age=\"27\">BRENT</user>  </user_db>  <foo><bar><foobar></foobar><goobar></goobar><hoobar></hoobar></bar><hi><dude></dude></hi></foo>") == 0 );

    etl_xml_node* root = xml.parse();
    assert( root != NULL );

    etl_xml_node* found = xml.search_for_first( "user", root );
    assert( found );

    assert( found->get_meta_data( "name" ) == "tony" );
    assert( found->get_meta_data( "age" ) == "27" );
    assert( found->get_data() == "TONY" );

    etl_hash<etl_string> metaSet = found->get_meta_data_set();

    assert( *metaSet.find("name") == "tony" );
    assert( *metaSet.find("age") == "27" );
  }

  {
    etl_xml xml;
    assert( xml.set_document("<?xml  version=\"1.0\"?><user_db num_users=\"3\"><user name=\"tony\" age=\"27\">TONY</user><user name=\"brad\" age=\"27\">BRAD</user>    <user name=\"brent\" age=\"27\">BRENT</user>  </user_db>  <foo><bar><foobar></foobar><goobar></goobar><hoobar></hoobar></bar><hi><dude></dude></hi></foo>") == 0 );

    etl_xml_node* root = xml.parse();
    assert( root != NULL );

    etl_xml_node* found = xml.seek( "?xml,user_db,user", root );
    assert( found );

    assert( found->get_meta_data( "name" ) == "tony" );
    assert( found->get_meta_data( "age" ) == "27" );
    assert( found->get_data() == "TONY" );
  }

  {
    etl_xml xml;

    etl_xml_node n1;
    etl_xml_node n2;
    etl_xml_node n3;
    n1.set_tag_name("foo");
    n1.add_meta_data("a","1");
    n1.add_meta_data("b","3");
    n1.set_data("This is n1 data");
    n1.append_child(&n2);
    n1.append_child(&n3);
    n2.set_tag_name("bar");
    n2.add_meta_data("b","2");
    n3.set_tag_name("moo");
    n3.add_meta_data("c","3");
    n3.set_data("foobar");
    etl_string doc;
    etl_xml::get_document(doc,&n1,true);

    xml.set_document( doc.c_str() );
    etl_xml_node* root = xml.parse();

    etl_xml_node* found = xml.search_for_first( "foo", root );
    assert( found );

    assert( found->get_meta_data( "b" ) == "3" );
    assert( found->get_meta_data( "a" ) == "1" );

    //XXX FAILS
    //assert( found->get_data() == "This is n1 data" );
  }

  {
      bool foundString = false;
      bool foundHash = false;
      bool foundList = false;

      etl_dir d("./*.cpp");
      d.iter_begin();
      while( d.iter_valid() )
      {
          etl_string file = *d.iter_data();

          if( file == "etl_string.cpp" )
              foundString = true;

          if( file == "etl_hash.cpp" )
              foundHash = true;

          if( file == "etl_list.cpp" )
              foundList = true;          

          d.iter_next();
      }

      assert( foundString && foundHash && foundList );
  }

  return 0;
}

